#ifndef _CALL_DLL_HPP_
#define _CALL_DLL_HPP_

#ifdef  __cplusplus

	#ifndef offsetof
	#define offsetof(s,m) ((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
	#endif // !offsetof

	class CPP_NO_VTABLE IImpModuleBase
	{
	public:
		struct STFunDesc
		{
			char *pFunName;
			size_t uOffFun;
		};
	public:

		TCHAR m_szModuleName[MAX_PATH];
		sentry<HMODULE, hmodule_sentry> m_hMod;

	public:
		virtual void InitIAT()
		{
			STFunDesc *pFunDesc=GetFunDefs();
			while(pFunDesc->pFunName)
			{	
				pFunDesc++;
			}
		}
	public:
		IImpModuleBase(const TCHAR *pModuleName):m_hMod(NULL)
		{

		}
		virtual ~IImpModuleBase()
		{
			UnLoad();
		}	
		virtual int Load()
		{
			STFunDesc *pFunDesc	=	GetFunDefs();
			m_hMod = loadlib(m_szModuleName, RTLD_LAZY);
			rc_assert(m_hMod, -1);
			while(string_stricmp(pFunDesc->pFunName,"null") != 0)
			{
				void *p = libfunc(m_hMod,pFunDesc->pFunName);

				SetFuncAddress(pFunDesc->uOffFun,p);
				if (!p)
				{
					rc_assert(Exception(m_hMod, pFunDesc->pFunName) == 0,-1)
				}
				pFunDesc++;
			}
				

			return 1;
		}
		virtual void UnLoad()
		{
			m_hMod.dispose();
		}
		virtual BOOL IsLoaded()
		{
			return NULL != m_hMod;
		}
		virtual bool Exception(HMODULE hModule, const char* lpProcName)
		{
			debug_view("IImpModuleBase->Exception")
			return true;
		}
		virtual STFunDesc *GetFunDefs() 			= 0;
		virtual bool SetFuncAddress(int i,void *p) 	= 0;
	};


#endif //  __cplusplus

#endif 
